﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.IO;
using System.Data.SQLite;

namespace KeyboardImageViewer
{
    /// <summary>
    /// Interaction logic for Duplicates.xaml
    /// </summary>
    public partial class Duplicates : Window
    {
        private const double ThumbnailHeight = 120;

        private ImageUserData selectedItem;
        private Grid selectedGrid;
        private List<Grid> duplicateGrids = new List<Grid>();

        private int currentImageId;
        private List<DuplicateImage> duplicates;

        public Duplicates(List<DuplicateImage> duplicates)
        {
            InitializeComponent();

            ImageManager.Config.ApplyWindowSize("Duplicate", this);

            this.DeletedImages = new List<int>();

            this.currentImageId = ImageListControl.CurrentImageId;
            this.duplicates = duplicates;

            ImageUserData currentImageData = Database.GetImageUserData(ImageManager.Connection, this.currentImageId);
            FileInfo currentFileInfo = new FileInfo(currentImageData.Name);

            this.AddImageToPanel(currentImageData, new string[] { ImageManager.Config.SourceDirectories.GetRelativeName(currentImageData.Name) + ", " + Utilities.ConvertBytesToString(currentFileInfo.Length), GetMetadataLine(currentImageData), "Current Image" });

            foreach (DuplicateImage duplicate in duplicates)
            {
                string duplicateTypeText;

                if (duplicate.ExactDuplicate)
                {
                    duplicateTypeText = "File-based Duplicate";
                }
                else
                {
                    duplicateTypeText = "Image-based Duplicate";
                }

                ImageUserData duplicateImageData = Database.GetImageUserData(ImageManager.Connection, duplicate.ImageId);
                FileInfo duplicateFileInfo = new FileInfo(duplicateImageData.Name);

                this.AddImageToPanel(duplicateImageData, new string[] { ImageManager.Config.SourceDirectories.GetRelativeName(duplicateImageData.Name) + ", " + Utilities.ConvertBytesToString(duplicateFileInfo.Length), GetMetadataLine(duplicateImageData), duplicateTypeText });
            }
        }

        public List<int> DeletedImages { get; set; }

        private void AddImageToPanel(ImageUserData imageData, string[] textRows)
        {
            Grid grid = new Grid();
            grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });

            for (int i = 0; i < textRows.Length; i++)
            {
                RowDefinition textRow = new RowDefinition { Height = GridLength.Auto };

                grid.RowDefinitions.Add(textRow);
            }

            Image image = new Image { Height = ThumbnailHeight };
            image.Margin = new Thickness(6);

            BitmapImage bitmapImage = new BitmapImage();
            bitmapImage.BeginInit();
            bitmapImage.DecodePixelHeight = (int)ThumbnailHeight;
            bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
            bitmapImage.UriSource = new Uri(imageData.Name);
            bitmapImage.EndInit();

            image.Source = bitmapImage;
            Grid.SetRow(image, 0);

            grid.Children.Add(image);

            for (int i = 0; i < textRows.Length; i++)
            {
                TextBlock textBlock = new TextBlock();
                textBlock.Text = textRows[i];
                textBlock.Padding = new Thickness(3);
                textBlock.HorizontalAlignment = HorizontalAlignment.Center;
                Grid.SetRow(textBlock, i + 1);

                grid.Children.Add(textBlock);
            }

            grid.Tag = imageData;
            grid.MouseLeftButtonDown += new MouseButtonEventHandler(grid_MouseLeftButtonDown);
            grid.MouseEnter += new MouseEventHandler(grid_MouseEnter);
            grid.MouseLeave += new MouseEventHandler(grid_MouseLeave);

            this.duplicateGrids.Add(grid);
            this.duplicateImagePanel.Children.Add(grid);
        }

        private void grid_MouseEnter(object sender, MouseEventArgs e)
        {
            Grid grid = (Grid)sender;
            if (grid.Background == null)
            {
                grid.Background = SharedUI.HoverColor;
            }
        }

        private void grid_MouseLeave(object sender, MouseEventArgs e)
        {
            Grid grid = (Grid)sender;
            if (grid.Background == SharedUI.HoverColor)
            {
                grid.Background = null;
            }
        }

        private void grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Grid clickedGrid = (Grid)sender;

            if (e.ClickCount == 1)
            {
                this.selectedItem = (ImageUserData)clickedGrid.Tag;
                this.selectedGrid = clickedGrid;

                foreach (Grid grid in this.duplicateGrids)
                {
                    grid.Background = null;
                }

                clickedGrid.Background = SharedUI.SelectColor;
                this.deleteButton.IsEnabled = true;
            }
            else if (e.ClickCount == 2)
            {
                Image clickedImage = clickedGrid.Children[0] as Image;

                if (clickedImage.Source == null)
                {
                    MessageBox.Show("Cannot show details. Image cannot be read.");
                }
                else
                {
                    ImageDetail imageDetail = new ImageDetail(this.selectedItem.Name);
                    imageDetail.Owner = this;
                    imageDetail.ShowDialog();
                }
            }
        }

        private void deleteButton_Click(object sender, RoutedEventArgs e)
        {
            this.DeleteCurrentDuplicate();
        }

        private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Delete)
            {
                this.DeleteCurrentDuplicate();
            }
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            ImageManager.Config.SaveWindowSize("Duplicate", this);
        }

        public static string GetMetadataLine(ImageUserData imageData)
        {
            string metadataLine = "";

            if (imageData.Tags.Count > 0)
            {
                metadataLine += "Tags: " + Utilities.SpaceListFromList(imageData.Tags);
            }

            if (imageData.Rating > 0)
            {
                if (metadataLine != "")
                {
                    metadataLine += "; ";
                }

                metadataLine += "Rating: " + imageData.Rating;
            }

            return metadataLine;
        }

        private void DeleteCurrentDuplicate()
        {
            if (this.selectedItem != null)
            {
                try
                {
                    // Delete file
                    File.Delete(this.selectedItem.Name);

                    this.DeletedImages.Add(this.selectedItem.Id);

                    this.duplicateImagePanel.Children.Remove(this.selectedGrid);

                    this.selectedItem = null;
                    this.selectedGrid = null;
                    this.deleteButton.IsEnabled = false;

                    if (this.duplicateImagePanel.Children.Count == 0)
                    {
                        this.Close();
                    }
                }
                catch (IOException)
                {
                    HandleDeleteException();
                }
                catch (UnauthorizedAccessException)
                {
                    HandleDeleteException();
                }
            }
        }

        private void HandleDeleteException()
        {
            MessageBox.Show("Could not delete file.  Make sure that it is not write-protected or in use.", "Error with file delete");
        }
    }
}
